import VUE from "vue";
import Lazy from './lib/lazy';

const install = (Vue: typeof VUE, options: VueLazyloadOptions = {}) => {
    const LazyClass = Lazy(Vue)
    const lazy = new LazyClass(options);
    Vue.prototype.$ImageLazyload = {
        $on(event: string, callback: VueLazyloadListenEvent) {
            lazy.$on(event, callback);
        },
        $once(event: string, callback: VueLazyloadListenEvent) {
            lazy.$once(event, callback);
        },
        $off(event: string, callback?: VueLazyloadListenEvent) {
            lazy.$off(event, callback);
        },
        lazyLoadHandler() {
            lazy.lazyLoadHandler();
        },
    }
    Vue.directive('lazy', {
        bind(el, binding, vnode, oldVnode) {
            lazy.add.bind(lazy)(el, binding, vnode, oldVnode);
        },
        update(el, binding, vnode, oldVnode) {
            lazy.update.bind(lazy)(el, binding, vnode, oldVnode);
        },
        componentUpdated(el, binding, vnode, oldVnode) {
            lazy.lazyLoadHandler.bind(lazy)(el, binding, vnode, oldVnode);
        },
        unbind(el, binding, vnode, oldVnode) {
            lazy.remove.bind(lazy)(el, binding, vnode, oldVnode);
        }
    })
};




export default install;

declare module 'vue/types/vue' {
    interface Vue {
        $ImageLazyload: VueLazyloadHandler;
    }
}



export interface VueLazyloadOptions {
    lazyComponent?: boolean;
    preLoad?: number;
    error?: string;
    loading?: string;
    attempt?: number;
    listenEvents?: string[];
    adapter?: any;
    filter?: any;
    dispatchEvent?: boolean;
    throttleWait?: number;
    observer?: boolean;
    observerOptions?: IntersectionObserverInit;
    silent?: boolean;
    preLoadTop?: number;
    scale?: number;
    hasbind?: boolean;
}

export interface VueLazyloadHandler {
    $on(event: string, callback: VueLazyloadListenEvent): void;
    $once(event: string, callback: VueLazyloadListenEvent): void;
    $off(event: string, callback?: VueLazyloadListenEvent): void;
    lazyLoadHandler(): void;
}
export interface VueLazyloadListenEvent {
    (listener: VueReactiveListener, cache: boolean): void;
}

export interface VueReactiveListener {
    el: Element;
    src: string;
    error: string;
    loading: string;
    bindType: string;
    attempt: number;
    naturalHeight: number;
    naturalWidth: number;
    options: VueLazyloadOptions;
    rect: DOMRect;
    $parent: Element
    elRenderer: Function;
    performanceData: {
        init: number,
        loadStart: number,
        loadEnd: number
    };
}